package com.ruoyi.coal.modules.coalpile.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;

import com.ruoyi.coal.common.utils.PageUtils;
import com.ruoyi.coal.common.utils.Query;
import com.ruoyi.coal.modules.coalpile.domain.TimingEntity;
import com.ruoyi.coal.modules.coalpile.mapper.TimingDao;
import com.ruoyi.coal.modules.coalpile.service.TimingService;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.coal.modules.coalpile.utils.schedule.Timed;

@Service("timingService")
@DataSource(value = DataSourceType.SLAVE)
public class TimingServiceImpl extends ServiceImpl<TimingDao, TimingEntity> implements TimingService {
//    @PostConstruct
//    @DataSource(value = DataSourceType.SLAVE)
    public void init() {
        List<TimingEntity> scheduleJobList = list();
        for (TimingEntity timingEntity : scheduleJobList) {
            if (timingEntity.getCronExpression() == null || timingEntity.getTimeSwitch().intValue() == 0)
                continue;
            Timed.setMonitor(timingEntity);
        }
    }

    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<TimingEntity> wrapper = new QueryWrapper();
        if (StringUtils.isNotEmpty((String)params.get("key")))
            wrapper.eq("coal_yard_id", params.get("key"));
        IPage<TimingEntity> page = page((new Query())
                .getPage(params), (Wrapper)wrapper);
        return new PageUtils(page);
    }

    @Transactional(rollbackFor = {Exception.class})
    public Boolean saveJob(TimingEntity timingEntity) {
        QueryWrapper<TimingEntity> wrapper = new QueryWrapper();
        wrapper.eq("coal_yard_id", timingEntity.getCoalYardId());
        if (verify(timingEntity, wrapper).booleanValue()) {
            String cronExpression = timingEntity.getTime().toString();
            String[] split = cronExpression.split(":");
            timingEntity.setCronExpression(split[2] + " " + split[1] + " " + split[0] + " * * ?");
            save(timingEntity);
            Timed.setMonitor(timingEntity);
            return Boolean.valueOf(true);
        }
        return Boolean.valueOf(false);
    }

    public Boolean updateJobById(TimingEntity timingEntity) {
        TimingEntity byId = (TimingEntity)getById(timingEntity.getId());
        QueryWrapper<TimingEntity> wrapper = new QueryWrapper();
        if (!byId.getTime().toString().equals(timingEntity.toString())) {
            ((QueryWrapper)wrapper.eq("coal_yard_id", timingEntity.getCoalYardId())).notIn("id", new Object[] { timingEntity.getId() });
            if (!verify(timingEntity, wrapper).booleanValue())
                return Boolean.valueOf(false);
        }
        String cronExpression = timingEntity.getTime().toString();
        String[] split = cronExpression.split(":");
        timingEntity.setCronExpression(split[2] + " " + split[1] + " " + split[0] + " * * ?");
        updateById(timingEntity);
        Timed.deleteSchedule(timingEntity.getId());
        if (timingEntity.getTimeSwitch().intValue() == 1)
            Timed.setMonitor(timingEntity);
        return Boolean.valueOf(true);
    }

    public void removeJob(Integer[] ids) {
        removeByIds(Arrays.asList(ids));
        for (Integer id : ids)
            Timed.deleteSchedule(id);
    }

    public Boolean verify(TimingEntity timingEntity, QueryWrapper<TimingEntity> wrapper) {
        List<TimingEntity> list = list((Wrapper)wrapper);
        if (list.size() != 0 || list != null)
            for (TimingEntity entity : list) {
                if (Math.abs(Timed.dateToStamp(entity.getTime().toString()).longValue() - Timed.dateToStamp(timingEntity.getTime().toString()).longValue()) < 600000L)
                    return Boolean.valueOf(false);
            }
        return Boolean.valueOf(true);
    }
}

